//////////////////////////////////////////////////////////////////////
//
//  CryEngine Source code
//	
//	File:SkeletonPose_Debug.cpp
//  Implementation of Skeleton class (Forward Kinematics)
//
//	History:
//	January 12, 2005: Created by Ivo Herzeg <ivo@crytek.de>
//
//////////////////////////////////////////////////////////////////////

#include "StdAfx.h"
#include <I3DEngine.h>
#include <IRenderAuxGeom.h>

#include "CharacterManager.h"
#include "CharacterInstance.h"
#include "Model.h"
#include "ModelSkeleton.h"

void CSkeletonPose::DrawBBox( const Matrix34& rRenderMat34 )
{
	//check if this is a skin attachment! if yes, don't draw the box	
	g_pAuxGeom->SetRenderFlags( e_Def3DPublicRenderflags );
	CAttachment* pAttachment = m_pInstance->m_pSkinAttachment;
	if (pAttachment && (pAttachment->GetType()==CA_SKIN || pAttachment->GetType()==CA_PART)) 
		return;

	OBB obb=OBB::CreateOBBfromAABB( Matrix33(rRenderMat34), m_AABB );
	Vec3 wpos=rRenderMat34.GetTranslation();
	g_pAuxGeom->DrawOBB(obb,wpos,0,RGBA8(0xff,0x00,0x1f,0xff),eBBD_Extremes_Color_Encoded);
}

void CSkeletonPose::DrawPose(const Skeleton::CPoseData& pose, QuatT transformation)
{

	CAttachment* pAttachment = m_pInstance->m_pSkinAttachment;
	if (pAttachment) if (pAttachment->GetType() == CA_SKIN || pAttachment->GetType() == CA_PART)
		return;

	g_pAuxGeom->SetRenderFlags(e_Def3DPublicRenderflags | e_DepthTestOff);

	static Ang3 ang_root(0,0,0); 
	ang_root += Ang3(0.01f,0.02f,0.03f);
	static Ang3 ang_rot(0,0,0); 
	ang_rot += Ang3(-0.01f,+0.02f,-0.03f);
	static Ang3 ang_pos(0,0,0); 
	ang_pos += Ang3(-0.03f,-0.02f,-0.01f);

	const QuatT* pJointsAbsolute = pose.GetJointsAbsolute();
	const Status4* pJointState = pose.GetJointsStatus();
	uint32 jointCount = pose.GetJointCount();

	QuatT jointTransformation;
	QuatT parentTransformation;
	for (uint32 i=0; i<jointCount; ++i)
	{
		jointTransformation = transformation * pJointsAbsolute[i];

		int32 parentIndex = m_parrModelJoints[i].m_idxParent;
		if (parentIndex > -1)
		{
			parentTransformation = transformation * pJointsAbsolute[parentIndex];
			g_pAuxGeom->DrawBone(parentTransformation, jointTransformation, RGBA8(0xff,0xff,0xff,0xc0));
		}

		/*
		if (pJointState[i].o || pJointState[i].p)
		{
			g_pAuxGeom->DrawSphere(jointTransformation.t, 0.01f, RGBA8(
				pJointState[i].o ? 0xc0 : 0x20, pJointState[i].p ? 0xc0 : 0x20, 0x20, 0xff));
		}*/

		f32 scale=0.1f;	
		static AABB aabb_rot	= AABB(Vec3(-0.011f,-0.011f,-0.011f)*scale,Vec3(+0.011f,+0.011f,+0.011f)*scale);
		Matrix33 m_rot				=	Matrix33::CreateRotationXYZ(ang_rot);
		OBB obb_rot						=	OBB::CreateOBBfromAABB( m_rot,aabb_rot );
		if (pJointState[i].o)
			g_pAuxGeom->DrawOBB(obb_rot,jointTransformation.t,0,RGBA8(0xff,0x00,0x00,0xff),eBBD_Extremes_Color_Encoded);

		static AABB aabb_pos	= AABB(Vec3(-0.010f,-0.010f,-0.010f)*scale,Vec3(+0.010f,+0.010f,+0.010f)*scale);
		Matrix33 m_pos				=	Matrix33::CreateRotationXYZ(ang_pos);
		OBB obb_pos						=	OBB::CreateOBBfromAABB( m_pos,aabb_pos );
		if (pJointState[i].p)
			g_pAuxGeom->DrawOBB(obb_pos,jointTransformation.t,0,RGBA8(0x00,0xff,0x00,0xff),eBBD_Extremes_Color_Encoded);

		g_pAuxGeom->DrawLine(jointTransformation.t, RGBA8(0xff, 0x80, 0x80, 0xff), jointTransformation.t + jointTransformation.GetColumn0() * 0.04f, RGBA8(0xff, 0x00, 0x00, 0xff));
		g_pAuxGeom->DrawLine(jointTransformation.t, RGBA8(0x80, 0xff, 0x80, 0xff), jointTransformation.t + jointTransformation.GetColumn1() * 0.04f, RGBA8(0x00, 0xff, 0x00, 0xff));
		g_pAuxGeom->DrawLine(jointTransformation.t, RGBA8(0x80, 0x80, 0xff, 0xff), jointTransformation.t + jointTransformation.GetColumn2() * 0.04f, RGBA8(0x00, 0x00, 0xff, 0xff));
	}
}

void CSkeletonPose::DrawSkeleton( const Matrix34& rRenderMat34, uint32 shift)
{
	DrawPose(GetPoseData(), QuatT(rRenderMat34));
}

void CSkeletonPose::DrawThinSkeletons( const QuatT& m34, const std::vector< std::vector<DebugJoint> >& arrSkeletons, int32 nAnimID,int32 nGlobalAnimID )
{
	if (nGlobalAnimID<0)
		return;

	static Ang3 angle(0,0,0); 
	angle+=Ang3(0.01f,0.02f,0.03f);

	GlobalAnimationHeaderCAF& rGlobalAnimHeader = g_AnimationManager.m_arrGlobalCAF[nGlobalAnimID];

	uint32 numSkeletons = arrSkeletons.size();
	for (uint32 s=0; s<numSkeletons; s++) 
		DrawThinSkeleton( m34, arrSkeletons[s], 0, RGBA8(0xff,0xff,0xff,0xff) );

//	DrawThinSkeleton( m34, arrSkeletons[s], rGlobalAnimHeader.m_FootPlantBits[s], RGBA8(0xff,0xff,0xff,0xff) );

}

void CSkeletonPose::DrawThinSkeleton( const QuatT& m34, const std::vector<DebugJoint>& arrSkeleton, uint8 FootPlant, ColorB col )
{
	static Ang3 angle(0,0,0); 
	angle+=Ang3(0.0001f,0.0002f,0.0003f);

	QuatT Pelvis	= arrSkeleton[0].m_AbsoluteQuat;
	QuatT WMat		= m34 * Pelvis;
	Vec3 WPos			=	WMat.t;


	Vec3 xaxis = WMat.GetColumn0()*0.15f;
	Vec3 yaxis = WMat.GetColumn1()*0.15f;
	Vec3 zaxis = WMat.GetColumn2()*0.15f;
	g_pAuxGeom->DrawLine(WPos, RGBA8(0xff,0x00,0x00,0), WPos+xaxis,RGBA8(0xff,0xff,0xff,0));
	g_pAuxGeom->DrawLine(WPos, RGBA8(0x00,0xff,0x00,0), WPos+yaxis,RGBA8(0xff,0xff,0xff,0));
	g_pAuxGeom->DrawLine(WPos, RGBA8(0x00,0x00,0xff,0), WPos+zaxis,RGBA8(0xff,0xff,0xff,0));



	{
		AABB aabb			= AABB(Vec3(-0.009f,-0.009f,-0.009f),Vec3(+0.009f,+0.009f,+0.009f));
		Matrix33 m33	=	Matrix33::CreateRotationXYZ(angle);
		OBB obb				=	OBB::CreateOBBfromAABB( m33,aabb );
		g_pAuxGeom->DrawOBB(obb,WPos,0,RGBA8(0xff,0x00,0x1f,0xff),eBBD_Extremes_Color_Encoded);
	}

	{
		AABB aabb			= AABB(Vec3(-0.002f,-0.002f,-0.002f),Vec3(+0.002f,+0.002f,+0.002f));
		Matrix33 m33	=	Matrix33::CreateRotationXYZ(angle);
		OBB obb				=	OBB::CreateOBBfromAABB( m33,aabb );

		int32 lHidx=m_pModelSkeleton->m_IdxArray[eIM_LHeelIdx];
		int32 rHidx=m_pModelSkeleton->m_IdxArray[eIM_RHeelIdx];
		if (lHidx>0 && rHidx>0)
		{
			if (FootPlant&LHEEL)
			{
				QuatT LWMat34	=	m34 * arrSkeleton[lHidx].m_AbsoluteQuat;
				g_pAuxGeom->DrawOBB(obb,LWMat34.t,0,RGBA8(0x00,0x00,0xff,0xff),eBBD_Extremes_Color_Encoded);
			}
			if (FootPlant&RHEEL)
			{
				QuatT RWMat34	=	m34 * arrSkeleton[rHidx].m_AbsoluteQuat;
				g_pAuxGeom->DrawOBB(obb,RWMat34.t,0,RGBA8(0x00,0x00,0xff,0xff),eBBD_Extremes_Color_Encoded);
			}
		}

		uint32 lTidx=m_pModelSkeleton->m_IdxArray[eIM_LToe0Idx];
		uint32 rTidx=m_pModelSkeleton->m_IdxArray[eIM_RToe0Idx];
		if (lTidx!=0xffff && rTidx!=0xffff)
		{
			if (FootPlant&LTOE0)
			{
				QuatT LWMat34	=	m34 * arrSkeleton[lTidx].m_AbsoluteQuat;
				g_pAuxGeom->DrawOBB(obb,LWMat34.t,0,RGBA8(0xff,0x00,0x00,0xff),eBBD_Extremes_Color_Encoded);
			}
			if (FootPlant&RTOE0)
			{
				QuatT RWMat34	=	m34 * arrSkeleton[rTidx].m_AbsoluteQuat;
				g_pAuxGeom->DrawOBB(obb,RWMat34.t,0,RGBA8(0xff,0x00,0x00,0xff),eBBD_Extremes_Color_Encoded);
			}
		}

	}


	uint32 numJoints = arrSkeleton.size();
	for (uint32 i=0; i<numJoints; i++)
	{

		int16 idxParent = arrSkeleton[i].m_idxParent;
		if (idxParent != -1)
		{

			QuatT WMatChild		=	m34 * arrSkeleton[i].m_AbsoluteQuat;
			QuatT WMatParent	=	m34 * arrSkeleton[idxParent].m_AbsoluteQuat;
			Vec3 JChild	  =	WMatChild.t;
			Vec3 JParent	=	WMatParent.t;
			f32 distance	= (JChild-JParent).GetLength();
			g_pAuxGeom->DrawLine( JParent,col, JChild,RGBA8(0x1f,0x1f,0x1f,0xff) );

		} 

	}
}

void CSkeletonPose::DrawArrow( const QuatT& location, const Vec3& vTravelDir, f32 length, ColorB col )
{
	SAuxGeomRenderFlags renderFlags( e_Def3DPublicRenderflags );
	g_pAuxGeom->SetRenderFlags( renderFlags );

	Vec3 absAxisY	=	location.q.GetColumn1();

	Vec3 vdir=vTravelDir.GetNormalized();
	Matrix33 m;
	m.m00=1;	m.m01=0;	m.m02=0;
	m.m10=0;	m.m11=0;	m.m12=-1;
	m.m20=0;	m.m21=1;	m.m22=0;
	f64 l = sqrt(vdir.x*vdir.x + vdir.y*vdir.y);
	if (l>0.0001)	
	{
		f32 rad			= f32( atan2(-vdir.z*(vdir.y/l),l) );
		m.SetRotationX(-rad);
	}

	//----------------------------------------------------------------------

	const f32 scale = 1.0f;
	const f32 size=0.009f;
	AABB yaabb = AABB(Vec3(-size*scale, -0.0f*scale, -size*scale),Vec3(size*scale,	 length*scale, size*scale));

	Matrix33 m2=Matrix33(location.q)*m;
	OBB obb =	OBB::CreateOBBfromAABB( Matrix33(location.q)*m, yaabb );
	g_pAuxGeom->DrawOBB(obb,location.t,1,col,eBBD_Extremes_Color_Encoded);

	if (l>0.0001)	
	{
		f64 xl=-vdir.x/l; f64 yl=vdir.y/l;
		m.m00=f32(yl);	m.m01=f32(vdir.x);		m.m02=f32(xl*vdir.z);
		m.m10=f32(xl);	m.m11=f32(vdir.y);		m.m12=f32(-vdir.z*yl);
		m.m20=0;				m.m21=f32(vdir.z);		m.m22=f32(l);
	}
	g_pAuxGeom->DrawCone(m2*(Vec3(0,1,0)*length*scale)+location.t, m2*Vec3(0,1,0),0.03f,0.15f,col);


}

void CSkeletonPose::DrawArrowArc( const QuatT& location, const f32 turnAngle, const f32 length, const f32 slope, const ColorB& col )
{
	f32 mSign = turnAngle >.0f? 1.0f : -1.0f;

	SAuxGeomRenderFlags renderFlags( e_Def3DPublicRenderflags );
	g_pAuxGeom->SetRenderFlags( renderFlags );

	Vec3 uprightVec(.0f, 0.0f, 1.0f);
	Matrix33 ma = Matrix33(location.q);//*m;
	Vec3 Va = ma * Vec3(.0f, 1.0f, .0f);

	//------------------------------------------------------------------------------
	// zero turning angles, straight-forward
	if(fabs(turnAngle) < 1e-10)
	{
		g_pAuxGeom->DrawLine(location.t, col, location.t + Va*length, col, 3.0f); //DrawOBB(obb,O,1,col,eBBD_Extremes_Color_Encoded);
		g_pAuxGeom->DrawCone(location.t + Va*length, Va, 0.03f,0.15f,col);
		return;
	}
	//------------------------------------------------------------------------------

	f32 r = fabs(length / turnAngle); // radius

	Matrix33 mb = Matrix33::CreateRotationAA(mSign* gf_PI/2.0f, Vec3(.0f, .0f, 1.0f));
	Vec3 Vt = mb*Va;
	Vt *= r;

	//g_pAuxGeom->DrawLine(location.t, RGBA8(0x00, 0xff, 0x00, 0xff), location.t + Vt, RGBA8(0x00, 0xff, 0x00, 0xff), 10.0f); //DrawOBB(obb,O,1,col,eBBD_Extremes_Color_Encoded);

	Vec3 O = location.t + Vt;
	Vec3 Vd = - Vt;

	static f32 arcSegNum = 30.0f;
	f32 stepSize = fabs(turnAngle) / arcSegNum;
	f32 offsetZ = 0.009f;
	for(f32 s=0.0f; s<fabs(turnAngle)-stepSize; s += stepSize)
	{
		Matrix33 m1 = Matrix33::CreateRotationAA(mSign* s, uprightVec);
		Matrix33 m2 = Matrix33::CreateRotationAA(mSign*(s+stepSize), uprightVec);
		Matrix33 mSlope = Matrix33::CreateRotationAA(mSign*slope, Vt.GetNormalized());

		Vec3 a = m1 * Vd;
		Vec3 b = m2 * Vd;

		g_pAuxGeom->DrawLine(mSlope*a + O + Vec3(.0f, .0f, offsetZ), col, mSlope*b + O + Vec3(.0f, .0f, offsetZ), col, 10.0f); //DrawOBB(obb,O,1,col,eBBD_Extremes_Color_Encoded);

		if( !( (s + stepSize) < (fabs(turnAngle)-stepSize) ) )
			g_pAuxGeom->DrawCone(mSlope*b+O, mSlope*(b-a), 0.05f,0.2f,col);
	}
}

void CSkeletonPose::DrawLocator(const QuatTS &rAnimLocationNext, const int cvarValue)
{
	SAuxGeomRenderFlags renderFlags( e_Def3DPublicRenderflags );
	g_pAuxGeom->SetRenderFlags( renderFlags );

	QuatT rel=m_pSkeletonAnim->GetRelMovement();
	QuatT offset = rel.GetInverted();
	if ( m_pSkeletonAnim->m_AnimationDrivenMotion)
		offset.t	=	Vec3(ZERO);

	QuatT BodyLocation = QuatT(rAnimLocationNext)*offset; 	
	BodyLocation.t += Vec3(0,0,0.01f);
	DrawArrow(BodyLocation,Vec3(0,1,0),1.0f,RGBA8(0x00,0xff,0x00,0x00) );

	//------------------------------

	Vec3 vMoveDirLocal=Vec3(ZERO);
	if (m_pInstance->m_fDeltaTime)
		vMoveDirLocal	=	rel.t/m_pInstance->m_fDeltaTime;
	f32 fLength								= vMoveDirLocal.GetLength();
	QuatT TravelArrowLocation = QuatT(rAnimLocationNext)*offset;
	f32 yaw = -atan2f(vMoveDirLocal.x,vMoveDirLocal.y);
	TravelArrowLocation.t += Vec3(0.0f,0.0f,0.00f);
	TravelArrowLocation.q *= Quat::CreateRotationZ(yaw);

	DrawArrow(TravelArrowLocation,vMoveDirLocal,fLength,RGBA8(0xff,0xff,0x00,0x00) ); // Replaced by DrawArrowArc

	if (cvarValue == 2)
	{
		float fColDebug2[4]={1,1,1,1};
		g_pIRenderer->Draw2dLabel( 1,g_YLine, 2.0f, fColDebug2, false,"vMoveDirLocal: %f %f", vMoveDirLocal.x, vMoveDirLocal.y );	
		g_YLine+=20.0f;
	}
}

void CSkeletonPose::DrawPositionPost(const QuatT& rPhysLocationNext, const QuatTS &rAnimLocationNext)
{
	if (Console::GetInst().ca_DrawPositionPost & 1)
	{
		//draw the entity in blue
		Vec3 wpos = rPhysLocationNext.t+Vec3(0.0f,0.0f,0.0f);
		g_pAuxGeom->SetRenderFlags( e_Def3DPublicRenderflags );
		static Ang3 angle(0,0,0);		angle += Ang3(0.01f,+0.03f,-0.07f);
		AABB aabb = AABB(Vec3(-0.05f,-0.05f,-0.05f),Vec3(+0.05f,+0.05f,+0.05f));
		OBB obb=OBB::CreateOBBfromAABB( Matrix33::CreateRotationXYZ(angle), aabb );
		g_pAuxGeom->DrawOBB(obb,wpos,1,RGBA8(0x00,0x00,0xff,0x00), eBBD_Extremes_Color_Encoded);

		Vec3 axisX = rPhysLocationNext.q.GetColumn0();
		Vec3 axisY = rPhysLocationNext.q.GetColumn1();
		Vec3 axisZ = rPhysLocationNext.q.GetColumn2();
		g_pAuxGeom->DrawLine(wpos,RGBA8(0x7f,0x00,0x00,0x00), wpos+axisX,RGBA8(0x7f,0x00,0x00,0x00) );
		g_pAuxGeom->DrawLine(wpos,RGBA8(0x00,0x7f,0x00,0x00), wpos+axisY,RGBA8(0x00,0x7f,0x00,0x00) );
		g_pAuxGeom->DrawLine(wpos,RGBA8(0x00,0x00,0x7f,0x00), wpos+axisZ,RGBA8(0x00,0x00,0x7f,0x00) );

		Vec3 line = rPhysLocationNext.q.GetColumn2()*5;

		g_pAuxGeom->DrawLine(wpos,RGBA8(0x00,0x00,0xff,0x00), wpos+line,RGBA8(0x00,0x00,0xff,0x00) );
	}
	if (Console::GetInst().ca_DrawPositionPost & 2) 
	{
		//draw the animated character in red
		Vec3 wpos = rAnimLocationNext.t+Vec3(0.0f,0.0f,0.0f);
		g_pAuxGeom->SetRenderFlags( e_Def3DPublicRenderflags );
		static Ang3 angle(0,0,0); 
		angle += Ang3(0.01f,-0.02f,-0.03f);
		AABB aabb = AABB(Vec3(-0.05f,-0.05f,-0.05f),Vec3(+0.05f,+0.05f,+0.05f));
		OBB obb=OBB::CreateOBBfromAABB( Matrix33::CreateRotationXYZ(angle), aabb );
		g_pAuxGeom->DrawOBB(obb,wpos,1,RGBA8(0xff,0x00,0x00,0x00), eBBD_Extremes_Color_Encoded);

		Vec3 axisX = rAnimLocationNext.q.GetColumn0();
		Vec3 axisY = rAnimLocationNext.q.GetColumn1();
		Vec3 axisZ = rAnimLocationNext.q.GetColumn2();
		g_pAuxGeom->DrawLine(wpos,RGBA8(0xff,0x00,0x00,0x00), wpos+axisX,RGBA8(0xff,0x00,0x00,0x00) );
		g_pAuxGeom->DrawLine(wpos,RGBA8(0x00,0xff,0x00,0x00), wpos+axisY,RGBA8(0x00,0xff,0x00,0x00) );
		g_pAuxGeom->DrawLine(wpos,RGBA8(0x00,0x00,0xff,0x00), wpos+axisZ,RGBA8(0x00,0x00,0xff,0x00) );

		Vec3 line = rAnimLocationNext.q.GetColumn2()*5;
		g_pAuxGeom->DrawLine(wpos,RGBA8(0xff,0x00,0x00,0x00), wpos+line,RGBA8(0xff,0x00,0x00,0x00) );
	}
}

void CSkeletonPose::DrawDebugCaps()
{
	if ( Console::GetInst().ca_DebugCaps )
	{
		int layer = 0;
		int animCount = m_pSkeletonAnim->GetNumAnimsInFIFO(layer);

		const char* szMotionParamID[eMotionParamID_COUNT] = 
		{
			"TravelAngle", "TravelDistScale", "TravelSpeed", "TravelDist", "TravelSlope", "TurnSpeed", "TurnAngle", "Duration"
		};

		for (int i = 0; i < animCount; ++i) 
		{
			f32 stride = f32(i * (eMotionParamID_COUNT + 1));
			CAnimation anim = m_pSkeletonAnim->GetAnimFromFIFO(layer, i);
			if (anim.m_bActivated && anim.m_Parametric)
			{
				const SParametric& lmg = *anim.m_Parametric;
				for (int id = 0; id < eMotionParamID_COUNT; ++id)
				{
					const MotionParamDesc& desc = lmg.m_params[id].desc;
					if (desc.m_nUsage != eMotionParamUsage_None)
					{
						if (!lmg.m_params[id].desc.m_bLocked)
						{
							const ColorF cCol(0.7f,1.0f,0.7f,1.0f);
							gEnv->pRenderer->Draw2dLabel(750, 100 + (stride + id) * 20, 1.3f, (float*)&cCol, false,	"%s [%3.2f %3.2f %3.2f %3.2f] %3.2f", szMotionParamID[id], desc.m_fMin, desc.m_fMinAsset, desc.m_fMaxAsset, desc.m_fMax, desc.m_fMaxChangeRate);
						}
						else
						{
							const ColorF cCol(1.0f,1.0f,0.7f,1.0f);
							gEnv->pRenderer->Draw2dLabel(750, 100 + (stride + id) * 20, 1.3f, (float*)&cCol, false,	"%s [%3.2f %3.2f %3.2f %3.2f] LOCK", szMotionParamID[id], desc.m_fMin, desc.m_fMinAsset, desc.m_fMaxAsset, desc.m_fMax);
						}
					}
					else
					{
						const ColorF cCol(1.0f,0.7f,0.7f,1.0f);
						gEnv->pRenderer->Draw2dLabel(750, 100 + (stride + id) * 20, 1.3f, (float*)&cCol, false,	"%s [ not supported ]", szMotionParamID[id]);
					}
				}
			}
		}
	}
}

f32 CSkeletonPose::SecurityCheck()
{
	f32 fRadius = 0.0f;
	uint32 numJoints = GetPoseData().GetJointCount();
	for (uint32 i=0; i<numJoints; i++)
	{
		f32 t=GetPoseData().m_pJointsAbsolute[i].t.GetLength();
		if (fRadius<t)
			fRadius=t;
	}
	return fRadius; 
}

uint32 CSkeletonPose::IsSkeletonValid()
{
	uint32 numJoints = GetPoseData().GetJointCount();
	for (uint32 i=0; i<numJoints; i++)
	{
		uint32 valid = GetPoseData().m_pJointsAbsolute[i].t.IsValid();
		if (valid==0)
			return 0;
		if ( fabsf(GetPoseData().m_pJointsAbsolute[i].t.x)>20000.0f )
			return 0;
		if ( fabsf(GetPoseData().m_pJointsAbsolute[i].t.y)>20000.0f )
			return 0;
		if ( fabsf(GetPoseData().m_pJointsAbsolute[i].t.z)>20000.0f )
			return 0;
	}
	return 1;
}

size_t CSkeletonPose::SizeOfThis()
{
	size_t TotalSize = 0;

	TotalSize += GetPoseData().GetAllocationLength();

	TotalSize += m_FaceAnimPosSmooth.get_alloc_size(); 
	TotalSize += m_FaceAnimPosSmoothRate.get_alloc_size(); 

	TotalSize += m_arrCGAJoints.get_alloc_size();
	TotalSize += m_arrPhysicsJoints.get_alloc_size();
	TotalSize += m_arrPostProcess.get_alloc_size();

	if (m_ppBonePhysics)
		TotalSize += GetPoseData().GetJointCount() * sizeof(IPhysicalEntity*);

	return TotalSize;
}

void CSkeletonPose::GetMemoryUsage(ICrySizer * pSizer) const
{
	pSizer->AddObject(m_poseData);
	pSizer->AddObject(m_LookAt);
	for( int i = 0 ; i < 12 ; ++i )
		pSizer->AddObject(m_auxPhys[i]);

	pSizer->AddObject(m_FaceAnimPosSmooth);
	pSizer->AddObject(m_FaceAnimPosSmoothRate);

	pSizer->AddObject(m_arrCGAJoints);
	pSizer->AddObject(m_arrPhysicsJoints);
	pSizer->AddObject(m_arrPostProcess);
	pSizer->AddObject(m_limbIk);

	pSizer->AddObject(m_PoseBlenderAim);
	pSizer->AddObject(m_PoseBlenderLook);
}
